import { Util } from '../../utils/util.js';
import { Definition } from './definition.js';
import { Engine } from '../engine.js';

export class CsFundDouble {
    static nan = NaN;
    static infinity = Infinity;
    static negativeInfinity = -Infinity;
    static minPositive = Number.MIN_VALUE;
    static maxFinite = Number.MAX_VALUE;
       _fixedPrecision = null;   // 固定精度，默认为 null, 采用商户设置精度

    static convertWithPresicesion(num, precision = null, precisionDown = null) {
        if (precision === null || precision >= 0) {
            return Util.convertWithPrecision(
                num,
                precision ?? Definition.fundPrecision,
               precisionDown ??  Engine.getOrgSettings().enableFundDecimalPrecisionDown
            );
        } else {
            return num;
        }
    }

    constructor(initValue = 0, precision = null, isFixedPrecision = false, precisionDown = null) {
        if (typeof initValue === 'string') {
            this._value = parseFloat(initValue);
            if (isNaN(this._value)) this._value = 0;
        } else if (initValue instanceof CsFundDouble) {
            this._value = CsFundDouble.convertWithPresicesion(initValue._value,precision,precisionDown);
        } else {
            this._value = CsFundDouble.convertWithPresicesion(initValue, precision,precisionDown);
        }

        if(isFixedPrecision) {
            this._fixedPrecision = precision;
        }
    }

    static zero() {
        return new CsFundDouble(0);
    }

    get value() {
        return this._value;
    }

    get fixedPrecision() {
        return this._fixedPrecision;
    }

    toDouble() {
        return this._value;
    }

    toString() {
        return this._value.toString();
    }

    equal(other) {
        return this._value === other._value;
    }

    abs() {
        return new CsFundDouble(Math.abs(this._value));
    }

    negate() {
        return new CsFundDouble(-this._value);
    }

    add(other) {
        return new CsFundDouble(this._value + other.toDouble());
    }

    sub(other) {
        return new CsFundDouble(this._value - other.toDouble());
    }

    mul(other) {
        return new CsFundDouble(this._value * other.toDouble());
    }

    div(other) {
        return new CsFundDouble(this._value / other.toDouble());
    }

    mod(other) {
        return new CsFundDouble(this._value % other.toDouble());
    }

    gt(other) {
        return this._value > other._value;
    }

    gte(other) {
        return this._value >= other._value;
    }

    lt(other) {
        return this._value < other._value;
    }

    lte(other) {
        return this._value <= other._value;
    }

    truncDivide(other) {
        return Math.trunc(this._value / other); // 模拟 Dart 的 ~/
    }
}
